package net.homelinux.chaoswg.io.renga.krypto.operations.type;

import java.math.BigInteger;

import net.homelinux.chaoswg.io.higherorderfunctions.AbstractUnaryFunction;
import net.homelinux.chaoswg.io.higherorderfunctions.UnaryFunction;
import net.homelinux.chaoswg.io.renga.core.helper.datatypes.Octet;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.UnsignedNBit;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.UnsignedNBitFactory;

public class Split8 extends AbstractUnaryFunction<Octet<UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit>, UnsignedNBit> implements UnaryFunction<Octet<UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit>, UnsignedNBit> {
    public Octet<UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit> apply (final UnsignedNBit unb) {
        final UnsignedNBitFactory unbFactory = UnsignedNBitFactory.createUnsignedNBitFactory();
        final int toSplitInto = 8;
        
        if (unbFactory.exists(unb.getN()/toSplitInto)) {
            final BigInteger [] u = new BigInteger [toSplitInto];
            final UnsignedNBit [] unbs = new UnsignedNBit [toSplitInto];

            final BigInteger val = unb.getValue();

            final BigInteger tmpMAX = unbFactory.get(unb.getN()/toSplitInto).getMAX();

            for (int i = 0; i < toSplitInto; ++i) {
                u[i] = val.shiftRight(i* (unb.getN() / toSplitInto)).and(tmpMAX);
                unbs [i] = unbFactory.get(unb.getN()/toSplitInto);
                unbs [i].setValue(u[i]);            
            }

            return new Octet<UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit, UnsignedNBit> (unbs[7], unbs[6], unbs[5],unbs[4],unbs[3],unbs[2],unbs[1], unbs[0]);
        }
        return null;
    }
    
    public String toString () {
        return "Split to eight";
    }
}
